using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
using WorkFlowCore.Authorization;
using WorkFlowCore.Common.Authorization.JWT;
using WorkFlowCore.Common.Tracers;
using WorkFlowCore.Plugins;

namespace WorkFlowCore.Framework.Authorization
{
    [PluginDescription("参数：token-from=[headers,query] token解析来源，默认 headers")]
    [PluginDescription("参数：token-key=[ThirdpartAuthorization] token名，默认 ThirdpartAuthorization")]
    [PluginDescription("参数：token-to=[headers,query] token解析来源，默认 headers")]
    [PluginDescription("参数：to-token-key=[authorization] token名，默认 authorization")]
    [PluginDescription("参数：method=[post,get] 请求方式，默认 get")]
    [PluginDescription("参数：token-format=Bearer {token}")]
    [PluginDescription("参数：url=[url] 认证地址")]
    [PluginDescription("返回值：{IsValid:bool,是否认证通过,User:{Id:string 用户唯一标识,Name:string 用户名称,IsManager:bool是否是管理员},Claims:[{type:\"\",value:\"\"}] 额外的身份信息，可为空}")]
    public class DefaultCustomizationVerifyExtension : ICustomizationVerifyExtension
    {
        private ConfigureContext configureContext;
        public async Task Configure(ConfigureContext configureContext)
        {
            this.configureContext = configureContext;
        }

        public VerifyOutput Verify(VerifyInput input)
        {
            using var activity = WorkflowActivitySource.Source?.StartActivity("DefaultCustomizationVerifyExtension");
            activity?.AddTag("appid", input.AppId ?? "null");
#if DEBUG
            Console.WriteLine($"DefaultCustomizationVerifyExtension-Verify:{input.AppId}");
#endif

            var tokenFrom = configureContext.Parameters.GetOrDefault("token-from") ?? "headers";
            var tokenKey = configureContext.Parameters.GetOrDefault("token-key") ?? "authorization";
            var tokenFormat = configureContext.Parameters.GetOrDefault("token-format") ?? "Bearer {token}";

            activity?.AddTag("tokenFrom", tokenFrom ?? "null");
            activity?.AddTag("tokenKey", tokenKey ?? "null");
            activity?.AddTag("tokenFormat", tokenFormat ?? "null");


            //直接解析第三方token标识，有就走插件认证
            var thirdpartAuthorization = input.Context.Request.Headers.GetOrDefault(tokenKey).ToString() ?? "";
            activity?.AddTag("thirdpartAuthorization", thirdpartAuthorization ?? "null");
            if (thirdpartAuthorization.IsNullOrWhiteSpace())
            {
                return new VerifyOutput
                {
                    IsValid = false,
                };
            }

            var token = string.Empty;
            if ("headers" == tokenFrom)
            {
                token = input.Context.Request.Headers.GetOrDefault(tokenKey).ToString();
            }
            else
            {
                token = input.Context.Request.Query[tokenKey].ToString();
                if (string.IsNullOrWhiteSpace(token))
                {
                    token = input.Context.Request.Form[tokenKey].ToString();
                }
            }

            var tokenTo = configureContext.Parameters.GetOrDefault("token-from") ?? "headers";
            var toTokenKey = configureContext.Parameters.GetOrDefault("to-token-key") ?? "authorization";
            activity?.AddTag("tokenTo", tokenTo ?? "null");
            activity?.AddTag("toTokenKey", toTokenKey ?? "null");
            if (token.IsNullOrWhiteSpace())
            {
                return new VerifyOutput
                {
                    IsValid = false,
                };
            }

            token = tokenFormat.Replace("{token}", token);
            activity?.AddTag("token", token ?? "null");
            var method = configureContext.Parameters.GetOrDefault("method") ?? "post";
            var url = $"{configureContext.Parameters.GetOrDefault("url")}?{toTokenKey}={token}";
            activity?.AddTag("url", url ?? "null");
            activity?.AddTag("method", method ?? "null");
            
            var handler = new HttpClientHandler();
            handler.ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => true; // 接受所有证书
            var httpClient = new HttpClient(handler);

            string result = null;
            VerifyOutput output = null;
            try
            {
                if (tokenTo == "headers")
                {
                    httpClient.DefaultRequestHeaders.Add(toTokenKey, token);
                }
                if (method == "post")
                {
                    var resp = httpClient.PostAsync(url, null).Result;
                    result = resp.Content.ReadAsStringAsync().Result;
                }
                else
                {
                    result = httpClient.GetStringAsync(url).Result;
                }

                JObject parsedResult = JObject.Parse(result);
                output = new VerifyOutput
                {
                    IsValid = parsedResult.GetValue("IsValid", StringComparison.OrdinalIgnoreCase)?.Value<bool>() ?? false
                };

                if (parsedResult.TryGetValue("User", StringComparison.OrdinalIgnoreCase, out JToken userToken) && userToken is JObject userJObject)
                {
                    output.User = new AuthorizationUser // WorkFlowCore.Common.Authorization.JWT.AuthorizationUser
                    {
                        Id = userJObject.GetValue("Id", StringComparison.OrdinalIgnoreCase)?.Value<string>(),
                        Name = userJObject.GetValue("Name", StringComparison.OrdinalIgnoreCase)?.Value<string>(),
                        IsManager = userJObject.GetValue("IsManager", StringComparison.OrdinalIgnoreCase)?.Value<bool>() ?? false
                        // AppId 将在后续逻辑中处理
                    };
                }

                if (parsedResult.TryGetValue("Claims", StringComparison.OrdinalIgnoreCase, out JToken claimsToken) && claimsToken is JArray claimsArray)
                {
                    var claimsList = new List<Claim>();
                    foreach (JToken claimToken in claimsArray)
                    {
                        if (claimToken is JObject claimJObject)
                        {
                            var type = claimJObject.GetValue("type", StringComparison.OrdinalIgnoreCase)?.Value<string>();
                            var value = claimJObject.GetValue("value", StringComparison.OrdinalIgnoreCase)?.Value<string>();
                            // 确保 type 和 value 都存在且不为空，才创建 Claim 对象
                            if (!string.IsNullOrEmpty(type) && value != null)
                            {
                                claimsList.Add(new Claim(type, value));
                            }
                        }
                    }
                    output.Claims = claimsList.ToArray();
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"DefaultCustomizationVerifyExtension Exception: {ex}, URL: {url}, Result: {result}");
                output = new VerifyOutput { IsValid = false };
            }
            if (output != null && output.IsValid && output.User != null && string.IsNullOrWhiteSpace(output.User.AppId))
            {
                output.User.AppId = input.AppId;
            }
            return output;
        }
    }
}
